package com.SRMS.service;

import com.SRMS.common.MessageType;
import com.SRMS.common.Message;
import com.SRMS.domain.*;

import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.net.Socket;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.List;

/**
 * @author Albert
 * @version 1.0
 * @date 2023/12/24-14:04
 * @describe 该类的一个对象和某个客户端保持通信
 */
public class ServerConnectClientThread extends Thread{

    private Socket socket;
    private boolean loop = true;

    public Socket getSocket() {
        return socket;
    }

    private String userId;//连接到服务器的用户id
    private StudentService studentService;
    private AdministratorService administratorService;

    public ServerConnectClientThread(Socket socket, String userId) {
        this.socket = socket;
        this.userId = userId;
    }

    public void setAdministratorService(AdministratorService administratorService) {
        this.administratorService = administratorService;
    }

    public void setStudentService(StudentService studentService) {
        this.studentService = studentService;
    }

    /**
     * 关闭线程
     */
    public void close(){
        loop = false;
    }

    /**
     * 获取当前时间
     * @return 当前时间
     */
    private String nowTime(){
        LocalDateTime ldt = LocalDateTime.now();
        DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
        String time = dateTimeFormatter.format(ldt);
        return time;
    }

    @Override
    public void run() {
        while(loop){
            try {
                System.out.println(nowTime() + " server and client" + userId + "keep connection...");
                ObjectInputStream ois = new ObjectInputStream(socket.getInputStream());
                Message message = (Message) ois.readObject();

                //根据message的类型，做相应的业务处理
                if (message.getMesType().equals(MessageType.MESSAGE_CLIENT_EXIT)) {
                    System.out.println(nowTime() + " user " + message.getSender() + " exit client");
                    //将这个客户端对应的服务端这边的线程从集合中删除
                    ManageClientThreads.removeServerConnectClientThread(message.getSender());
                    socket.close();//关闭连接
                    //退出线程
                    loop = false;
                } else if (message.getMesType().equals(MessageType.GET_STUDY_ROOM_LIST_FOR_STUDENT)) {
                    System.out.println(nowTime() + " 学生 " + message.getSender() + " 要求返回自习室列表");
                    List<StudyRoom> studyRoomList = studentService.studyRoomList();
                    Message messageReturn = new Message();
                    messageReturn.setMesType(MessageType.RET_STUDY_ROOM_LIST_FOR_STUDENT);
                    messageReturn.setStudyRoomList(studyRoomList);
                    //返回给客户端
                    ObjectOutputStream oos = new ObjectOutputStream(socket.getOutputStream());
                    oos.writeObject(messageReturn);
                } else if (message.getMesType().equals(MessageType.GET_RIGHT_FOR_STUDENT)) {
                    System.out.println(nowTime() + " 学生 " + message.getSender() + " 要求返回自习室使用权");
                    RightToUseStudyRoom rightToUseStudyRoom = studentService.getRightByStuId(message.getSender());
                    Message messageReturn = new Message();
                    messageReturn.setMesType(MessageType.RET_RIGHT_FOR_STUDENT);
                    messageReturn.setRightToUseStudyRoom(rightToUseStudyRoom);
                    //返回给客户端
                    ObjectOutputStream oos = new ObjectOutputStream(socket.getOutputStream());
                    oos.writeObject(messageReturn);
                } else if (message.getMesType().equals(MessageType.GET_STUDY_ROOM_FOR_STUDENT)) {
                    System.out.println(nowTime() + " 学生 " + message.getSender() + " 要求返回所查找的自习室");
                    StudyRoom studyRoom = studentService.getStudyRoomById(message.getStudyRoomId());
                    Message messageReturn = new Message();
                    messageReturn.setMesType(MessageType.RET_STUDY_ROOM_FOR_STUDENT);
                    messageReturn.setStudyRoom(studyRoom);
                    //返回给客户端
                    ObjectOutputStream oos = new ObjectOutputStream(socket.getOutputStream());
                    oos.writeObject(messageReturn);
                } else if (message.getMesType().equals(MessageType.APPLY_STUDY_ROOM)) {
                    System.out.println(nowTime() + " 学生 " + message.getSender() + " 要求申请自习室");
                    boolean result = studentService.applyStudyRoom(message.getRemainingSeats(), message.getStudyRoomId(), message.getSender());
                    Message messageReturn = new Message();
                    messageReturn.setMesType(MessageType.RET_RESULT_OF_APPLY_STUDY_ROOM);
                    messageReturn.setResult(result);
                    //返回给客户端
                    ObjectOutputStream oos = new ObjectOutputStream(socket.getOutputStream());
                    oos.writeObject(messageReturn);
                } else if (message.getMesType().equals(MessageType.GET_APPLIED_STUDY_ROOM)) {
                    System.out.println(nowTime() + " 学生 " + message.getSender() + " 要求返回所申请到的自习室");
                    RoomForStudent roomForStudent = studentService.getAppliedStudyRoom(message.getSender());
                    Message messageReturn = new Message();
                    messageReturn.setMesType(MessageType.RET_APPLIED_STUDY_ROOM);
                    messageReturn.setRoomForStudent(roomForStudent);
                    //返回给客户端
                    ObjectOutputStream oos = new ObjectOutputStream(socket.getOutputStream());
                    oos.writeObject(messageReturn);
                } else if (message.getMesType().equals(MessageType.RETURN_RIGHT)) {
                    System.out.println(nowTime() + " 学生 " + message.getSender() + " 要求归还自习室使用权");
                    boolean result = studentService.returnRight(message.getRightToUseStudyRoom());
                    Message messageReturn = new Message();
                    messageReturn.setMesType(MessageType.RET_RESULT_OF_RETURN_RIGHT);
                    messageReturn.setResult(result);
                    //返回给客户端
                    ObjectOutputStream oos = new ObjectOutputStream(socket.getOutputStream());
                    oos.writeObject(messageReturn);
                } else if (message.getMesType().equals(MessageType.GET_HISTORY_FOR_STUDENT)) {
                    System.out.println(nowTime() + " 学生 " + message.getSender() + " 要求返回自己的自习室历史使用记录列表");
                    List<HistoryForStudent> historyForStudents = studentService.getHistoryForStudentByStudentId(message.getSender());
                    Message messageReturn = new Message();
                    messageReturn.setMesType(MessageType.RET_HISTORY_FOR_STUDENT);
                    messageReturn.setHistoryForStudentList(historyForStudents);
                    //返回给客户端
                    ObjectOutputStream oos = new ObjectOutputStream(socket.getOutputStream());
                    oos.writeObject(messageReturn);
                } else if (message.getMesType().equals(MessageType.GET_RIGHT_RECORD_LIST)) {
                    System.out.println(nowTime() + " 管理员 " + message.getSender() + " 要求返回所有的自习室使用权信息列表");
                    List<RightRecord> rightRecords = administratorService.getRightManageService().rightList();
                    Message messageReturn = new Message();
                    messageReturn.setMesType(MessageType.RET_RIGHT_RECORD_LIST);
                    messageReturn.setRightRecords(rightRecords);
                    //返回给客户端
                    ObjectOutputStream oos = new ObjectOutputStream(socket.getOutputStream());
                    oos.writeObject(messageReturn);
                } else if (message.getMesType().equals(MessageType.GET_RIGHT_FOR_ADMINISTRATOR)) {
                    System.out.println(nowTime() + " 管理员 " + message.getSender() + " 要求返回指定学生的自习室使用权");
                    RightToUseStudyRoom rightToUseStudyRoom = administratorService.getRightManageService().getRightByStuId(message.getStudentId());
                    Message messageReturn = new Message();
                    messageReturn.setMesType(MessageType.RET_RIGHT_FOR_ADMINISTRATOR);
                    messageReturn.setRightToUseStudyRoom(rightToUseStudyRoom);
                    //返回给客户端
                    ObjectOutputStream oos = new ObjectOutputStream(socket.getOutputStream());
                    oos.writeObject(messageReturn);
                } else if (message.getMesType().equals(MessageType.REVOKE_RIGHT)) {
                    System.out.println(nowTime() + " 管理员 " + message.getSender() + " 要求撤销指定学生的自习室使用权");
                    boolean result = administratorService.getRightManageService().revokeRightByStudentId(message.getStudentId(), userId, message.getRevokeReason());
                    Message messageReturn = new Message();
                    messageReturn.setMesType(MessageType.RET_RESULT_REVOKE_RIGHT);
                    messageReturn.setResult(result);
                    //返回给客户端
                    ObjectOutputStream oos = new ObjectOutputStream(socket.getOutputStream());
                    oos.writeObject(messageReturn);
                } else if (message.getMesType().equals(MessageType.GET_REVOKE_RECORD_LIST)) {
                    System.out.println(nowTime() + " 管理员 " + message.getSender() + " 要求返回撤销记录列表");
                    List<RevokeRecordForAdmin> revokeRecordForAdmins = administratorService.getRightManageService().revokeRecordForAdminList();
                    Message messageReturn = new Message();
                    messageReturn.setMesType(MessageType.RET_REVOKE_RECORD_LIST);
                    messageReturn.setRevokeRecordForAdmins(revokeRecordForAdmins);
                    //返回给客户端
                    ObjectOutputStream oos = new ObjectOutputStream(socket.getOutputStream());
                    oos.writeObject(messageReturn);
                } else if (message.getMesType().equals(MessageType.GET_STUDENT)) {
                    System.out.println(nowTime() + " 管理员 " + message.getSender() + " 要求返回所查询的学生");
                    Student student = administratorService.getStudentManageService().getStudentById(message.getStudentId());
                    Message messageReturn = new Message();
                    messageReturn.setMesType(MessageType.RET_STUDENT);
                    messageReturn.setStudent(student);
                    //返回给客户端
                    ObjectOutputStream oos = new ObjectOutputStream(socket.getOutputStream());
                    oos.writeObject(messageReturn);
                } else if (message.getMesType().equals(MessageType.ADD_STUDENT)) {
                    System.out.println(nowTime() + " 管理员 " + message.getSender() + " 要求添加学生");
                    boolean result = administratorService.getStudentManageService().addStudent(message.getStudent());
                    Message messageReturn = new Message();
                    messageReturn.setMesType(MessageType.RET_RESULT_OF_ADD_STUDENT);
                    messageReturn.setResult(result);
                    //返回给客户端
                    ObjectOutputStream oos = new ObjectOutputStream(socket.getOutputStream());
                    oos.writeObject(messageReturn);
                } else if (message.getMesType().equals(MessageType.UPDATE_STUDENT)) {
                    System.out.println(nowTime() + " 管理员 " + message.getSender() + " 要求修改学生");
                    boolean result = administratorService.getStudentManageService().updateStudent(message.getStudent());
                    Message messageReturn = new Message();
                    messageReturn.setMesType(MessageType.RET_RESULT_OF_UPDATE_STUDENT);
                    messageReturn.setResult(result);
                    //返回给客户端
                    ObjectOutputStream oos = new ObjectOutputStream(socket.getOutputStream());
                    oos.writeObject(messageReturn);
                } else if (message.getMesType().equals(MessageType.DELETE_STUDENT)) {
                    System.out.println(nowTime() + " 管理员 " + message.getSender() + " 要求删除学生");
                    boolean result = administratorService.getStudentManageService().deleteStudentById(message.getStudentId());
                    ServerConnectClientThread scct = ManageClientThreads.getServerConnectClientThread(message.getStudentId());
                    ManageClientThreads.removeServerConnectClientThread(message.getStudentId());
                    if (scct != null) {
                        scct.socket.close();//关闭连接
                        scct.close();//关闭线程
                    }
                    Message messageReturn = new Message();
                    messageReturn.setMesType(MessageType.RET_RESULT_OF_DELETE_STUDENT);
                    messageReturn.setResult(result);
                    //返回给客户端
                    ObjectOutputStream oos = new ObjectOutputStream(socket.getOutputStream());
                    oos.writeObject(messageReturn);
                } else if (message.getMesType().equals(MessageType.GET_STUDENT_LIST)) {
                    System.out.println(nowTime() + " 管理员 " + message.getSender() + " 要求查询所有学生");
                    List<Student> students = administratorService.getStudentManageService().studentList();
                    Message messageReturn = new Message();
                    messageReturn.setMesType(MessageType.RET_STUDENT_LIST);
                    messageReturn.setStudents(students);
                    //返回给客户端
                    ObjectOutputStream oos = new ObjectOutputStream(socket.getOutputStream());
                    oos.writeObject(messageReturn);
                } else if (message.getMesType().equals(MessageType.GET_STUDY_ROOM_FOR_ADMINISTRATOR)) {
                    System.out.println(nowTime() + " 管理员 " + message.getSender() + " 要求查询指定自习室");
                    StudyRoom studyRoom = administratorService.getStudyRoomManageService().getStudyRoomById(message.getStudyRoomId());
                    Message messageReturn = new Message();
                    messageReturn.setMesType(MessageType.RET_STUDY_ROOM_FOR_ADMINISTRATOR);
                    messageReturn.setStudyRoom(studyRoom);
                    //返回给客户端
                    ObjectOutputStream oos = new ObjectOutputStream(socket.getOutputStream());
                    oos.writeObject(messageReturn);
                } else if (message.getMesType().equals(MessageType.ADD_STUDY_ROOM)) {
                    System.out.println(nowTime() + " 管理员 " + message.getSender() + " 要求添加自习室");
                    boolean result = administratorService.getStudyRoomManageService().addStudyRoom(message.getStudyRoom());
                    Message messageReturn = new Message();
                    messageReturn.setMesType(MessageType.RET_RESULT_OF_ADD_STUDY_ROOM);
                    messageReturn.setResult(result);
                    //返回给客户端
                    ObjectOutputStream oos = new ObjectOutputStream(socket.getOutputStream());
                    oos.writeObject(messageReturn);
                } else if (message.getMesType().equals(MessageType.UPDATE_STUDY_ROOM)) {
                    System.out.println(nowTime() + " 管理员 " + message.getSender() + " 要求修改自习室");
                    boolean result = administratorService.getStudyRoomManageService().updateStudyRoom(message.getStudyRoom());
                    Message messageReturn = new Message();
                    messageReturn.setMesType(MessageType.RET_RESULT_OF_UPDATE_STUDY_ROOM);
                    messageReturn.setResult(result);
                    //返回给客户端
                    ObjectOutputStream oos = new ObjectOutputStream(socket.getOutputStream());
                    oos.writeObject(messageReturn);
                } else if (message.getMesType().equals(MessageType.DELETE_STUDY_ROOM)) {
                    System.out.println(nowTime() + " 管理员 " + message.getSender() + " 要求删除自习室");
                    boolean result = administratorService.getStudyRoomManageService().deleteStudyRoomById(message.getStudyRoomId());
                    Message messageReturn = new Message();
                    messageReturn.setMesType(MessageType.RET_RESULT_OF_DELETE_STUDY_ROOM);
                    messageReturn.setResult(result);
                    //返回给客户端
                    ObjectOutputStream oos = new ObjectOutputStream(socket.getOutputStream());
                    oos.writeObject(messageReturn);
                } else if (message.getMesType().equals(MessageType.GET_STUDY_ROOM_LIST_FOR_ADMINISTRATOR)) {
                    System.out.println(nowTime() + " 管理员 " + message.getSender() + " 要求查询所有的自习室");
                    List<StudyRoom> studyRooms = administratorService.getStudyRoomManageService().studyRoomList();
                    Message messageReturn = new Message();
                    messageReturn.setMesType(MessageType.RET_STUDY_ROOM_LIST_FOR_ADMINISTRATOR);
                    messageReturn.setStudyRoomList(studyRooms);
                    //返回给客户端
                    ObjectOutputStream oos = new ObjectOutputStream(socket.getOutputStream());
                    oos.writeObject(messageReturn);
                } else if (message.getMesType().equals(MessageType.GET_HISTORY_OF_ROOM_USAGE)) {
                    System.out.println(nowTime() + " 管理员 " + message.getSender() + " 要求查询所有的自习室使用记录");
                    List<HistoryOfRoomUsage> historyOfRoomUsages = administratorService.getStudyRoomManageService().historyOfRoomUsageList();
                    Message messageReturn = new Message();
                    messageReturn.setMesType(MessageType.RET_HISTORY_OF_ROOM_USAGE);
                    messageReturn.setHistoryOfRoomUsages(historyOfRoomUsages);
                    //返回给客户端
                    ObjectOutputStream oos = new ObjectOutputStream(socket.getOutputStream());
                    oos.writeObject(messageReturn);
                }


            } catch (Exception e) {
                e.printStackTrace();
                loop = false;
            }
        }
    }
}
